package cn.y.operation.framework.utils.dev;

import org.apache.commons.lang3.time.DateFormatUtils;

import java.lang.management.ManagementFactory;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

import java.time.LocalDateTime;
import java.time.ZoneOffset;

public class DateUtils extends org.apache.commons.lang3.time.DateUtils {

    public static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
    public static final String YYYY_MM_DD_HH_MM = "yyyy-MM-dd HH:mm";
    public static final String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
    public static final String YYYYMMDDHHMM = "yyyyMMddHHmm";
    public static final String YYYYMMDD = "yyyyMMdd";
    public static final String ISO8601 = "yyyy-MM-dd'T'HH:mm:ssXXX";

    public static final SimpleDateFormat YYYY_MM_DD_HH_MM_SS_Format = new SimpleDateFormat(YYYY_MM_DD_HH_MM_SS);
    public static final SimpleDateFormat YYYY_MM_DD_HH_MM_Format = new SimpleDateFormat(YYYY_MM_DD_HH_MM);
    public static final SimpleDateFormat YYYYMMDDHHMMSS_Format = new SimpleDateFormat(YYYYMMDDHHMMSS);
    public static final SimpleDateFormat YYYYMMDDHHMM_Format = new SimpleDateFormat(YYYYMMDDHHMM);
    public static final SimpleDateFormat YYYYMMDD_Format = new SimpleDateFormat(YYYYMMDD);
    public static final SimpleDateFormat ISO8601_Format = new SimpleDateFormat(ISO8601);

    public static void main(String[] args) throws Exception {
        System.out.println(ISO8601_Format.parse("2021-01-11T15:30:00Z").getTime());
        System.out.println(ISO8601_Format.parse("2021-03-26T17:31:18+01:00").getTime());

    }

    public static String getZoneOffset() {
        return LocalDateTime.now(ZoneOffset.systemDefault()).atZone(ZoneOffset.systemDefault()).getOffset().toString();
    }

    public static Date getDate() {
        return new Date(System.currentTimeMillis());
    }

    /**
     * 得到当前日期字符串 格式（yyyy-MM-dd HH:mm:ss）
     */
    public static Date getFormatDate() {
        return getFormatDate(YYYY_MM_DD_HH_MM_SS);
    }

    /**
     * 得到当前日期字符串 格式（yyyy-MM-dd） pattern可以为："yyyy-MM-dd" "HH:mm:ss" "E"
     */
    public static Date getFormatDate(String format) {
        return getFormatToDate(getDateToString(format), format);
    }

    /**
     * 按指定格式转Date
     */
    public static Date getFormatToDate(String date, String format) {
        try {
            return new SimpleDateFormat(format).parse(date);
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 得到当前日期字符串 格式（yyyy-MM-dd HH:mm:ss）
     */
    public static String getDateToString() {
        return getDateToString(YYYY_MM_DD_HH_MM_SS);
    }

    /**
     * 得到当前日期字符串 格式（yyyy-MM-dd HH:mm:ss）
     */
    public static String getDateToString(String pattern) {
        return getDateToString(getDate(), pattern);
    }

    public static String getDateToString(Date date, String format) {
        SimpleDateFormat formatter = new SimpleDateFormat(format);
        return formatter.format(date);
    }

    public static Long getDateToLong() throws ParseException {
        return getDateToLong(YYYY_MM_DD_HH_MM_SS);
    }

    public static Long getDateToLong(String format) throws ParseException {
        return getDateToLong(getDateToString(), format);
    }

    public static Long getDateToLong(String date, String format) throws ParseException {
        return getFormatToDate(date, format).getTime();
    }

    //----------------------------------------------------------------------------------------------

    /**
     * 获取服务器启动时间
     */
    public static Date getServerStartDate() {
        long time = ManagementFactory.getRuntimeMXBean().getStartTime();
        return new Date(time);
    }

    /**
     * 得到指定日期后 1天日期
     */
    public static Date getNextDate(Date date) {
        return getNextDate(date, 1);
    }

    /**
     * 得到指定日期后 N天日期
     */
    public static Date getNextDate(Date date, int day) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DATE, day);
        return calendar.getTime();
    }

    /**
     * 得到今天后N 天日期
     */
    public static String getNextWeekDate(int day) {
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.DATE, day);
        return formatDate(cal.getTime(), "yyyy-MM-dd");
    }


    /**
     * 得到日期字符串 默认格式（yyyy-MM-dd） pattern可以为："yyyy-MM-dd" "HH:mm:ss" "E"
     */
    public static String formatDate(Date date, Object... pattern) {
        String formatDate = null;
        if (pattern != null && pattern.length > 0) {
            formatDate = DateFormatUtils.format(date, pattern[0].toString());
        } else {
            formatDate = DateFormatUtils.format(date, "yyyy-MM-dd");
        }
        return formatDate;
    }

    /**
     * <p>Description： 获取时间是上午还是下午，0：上午，1:下午</p>
     *
     * @param date 格式化的日期時間 ，pattern 格式
     * @return
     * @author leiqing on  2018/7/5 11:23
     * @url
     */
    public static int getAM_PM(String date, String pattern) {
        try {
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
            GregorianCalendar gregorianCalendar = new GregorianCalendar();
            gregorianCalendar.setTime(simpleDateFormat.parse(date));
            return gregorianCalendar.get(GregorianCalendar.AM_PM);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return -1;
    }

    /**
     * <p>Description：时间差（分） </p>
     *
     * @param first 第一个时间
     * @param first 第二个时间
     * @return
     * @author leiqing on  2018/3/15 10:57
     */
    public static int timestampesMin(Date first, Date second) {
        if (first != null && second != null) {
            long from = first.getTime();
            long to = second.getTime();
            return (int) ((to - from) / (1000 * 60));
        } else {
            return 0;
        }
    }

    /**
     * 与当前日期比较大小，是今天以前日期小于0，以后日期大于0
     */
    public static int compareToToday(String originDate) {

        try {
            Calendar calendar = Calendar.getInstance();
            SimpleDateFormat formatDate = new SimpleDateFormat("yyyy-MM-dd");
            String currentTime = formatDate.format(calendar.getTime());
            Date today = formatDate.parse(currentTime);
            Date target = formatDate.parse(originDate);
            return target.compareTo(today);
        } catch (Exception e) {
            return 0;
        }
    }


    /**
     * 得到当前月份最后一天
     *
     * @param date
     * @return
     */
    public static String getMonthEnd(String date) throws Exception {

        Date d = parseDate(date, "yyyy-MM-dd");

        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(d);

        // 最后一天
        calendar.add(Calendar.MONTH, 1); // 加一个月
        calendar.set(Calendar.DATE, 1); // 设置为该月第一天
        calendar.add(Calendar.DATE, -1); // 再减一天即为最后一天
        String day_last = df.format(calendar.getTime());

        return day_last;
    }

    /**
     * 获得当月 周六周日对应的日期
     */
    public static String getWeeks(String date) {
        // String date = "2013-09";
        StringBuilder sb = new StringBuilder();

        try {
            DateFormat dateFormat = new SimpleDateFormat("yyyy-MM");
            Date date1 = dateFormat.parse(date);
            Calendar calendar = new GregorianCalendar();
            calendar.setTime(date1);
            int days = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);

            for (int i = 1; i <= days; i++) {
                DateFormat dateFormat1 = new SimpleDateFormat("yyyy-MM-dd");
                Date date2 = dateFormat1.parse(date + "-" + i);
                calendar.clear();
                calendar.setTime(date2);
                // 周日是1 周六是7
                int k = calendar.get(Calendar.DAY_OF_WEEK);
                if (k == 1 || k == 7) {
                    sb.append(DateFormatUtils.format(date2, "yyyy-MM-dd"));
                    sb.append(",");
                }
            }
        } catch (Exception e) {
            // TODO: handle exception
        }
        return sb.toString().substring(0, sb.toString().lastIndexOf(","));
    }


    //获取本周的开始时间
    public static Date getBeginDayOfWeek() {
        Date date = getDate();
        if (date == null) {
            return null;
        }
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int dayofweek = cal.get(Calendar.DAY_OF_WEEK);
        if (dayofweek == 1) {
            dayofweek += 7;
        }
        cal.add(Calendar.DATE, 2 - dayofweek);
        return getDayStartTime(cal.getTime());
    }

    //获取本周的结束时间
    public static Date getEndDayOfWeek() {
        Calendar cal = Calendar.getInstance();
        cal.setTime(getBeginDayOfWeek());
        cal.add(Calendar.DAY_OF_WEEK, 6);
        Date weekEndSta = cal.getTime();
        return getDayEndTime(weekEndSta);
    }

    //获取某个日期的开始时间
    public static Timestamp getDayStartTime(Date d) {
        Calendar calendar = Calendar.getInstance();
        if (null != d) {
            calendar.setTime(d);
        }
        calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return new Timestamp(calendar.getTimeInMillis());
    }

    //获取某个日期的结束时间
    public static Timestamp getDayEndTime(Date d) {
        Calendar calendar = Calendar.getInstance();
        if (null != d) {
            calendar.setTime(d);
        }
        calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH), 23, 59, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        return new Timestamp(calendar.getTimeInMillis());
    }

    //获取本月的开始时间
    public static Date getBeginDayOfMonth() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(getNowYear(), getNowMonth() - 1, 1);
        return getDayStartTime(calendar.getTime());
    }

    //获取本月的结束时间
    public static Date getEndDayOfMonth() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(getNowYear(), getNowMonth() - 1, 1);
        int day = calendar.getActualMaximum(5);
        calendar.set(getNowYear(), getNowMonth() - 1, day);
        return getDayEndTime(calendar.getTime());
    }

    //获取今年是哪一年
    public static Integer getNowYear() {
        Date date = getDate();
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(date);
        return gc.get(Calendar.YEAR);
    }

    //获取本月是哪一月
    public static int getNowMonth() {
        Date date = getDate();
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(date);
        return gc.get(2) + 1;
    }

    /**
     * 格式化秒，转换为时分秒
     *
     * @param seconds
     * @return
     */
    public static String formatSeconds(int seconds) {
        String result = null;
        int hour = 0, min = 0, sec = 0;
        hour = seconds / 3600;
        min = seconds / 60 % 60;
//        sec = seconds % 60;
        if (seconds >= 3600) {
            result = hour + "小时" + min + "分钟";
        } else if (seconds >= 60) {
            result = min + "分钟";
        }
        return result;
    }

}
